import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.transform.Scale;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

import java.io.File;
import java.text.DecimalFormat;

public class JImageView extends Application {

    String iconSrc = "img/icon.png";

    String title = "JImageView";

    private static final String TITLE = "打开图片";
    private static final String SIZE_LABEL = "大小：";
    private static final String DIMENSIONS_LABEL = "\t尺寸：";
    private static final String UNIT = " KB";

    private ImageView imageView;
    private Scale scaleTransform;

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle(title);
        BorderPane root = new BorderPane();

        // Create a TabPane to display multiple images
        TabPane tabPane = new TabPane();
        root.setCenter(tabPane);

        // Create toolbar
        Button openButton = new Button("打开");
        openButton.setOnAction(e -> openImage(primaryStage, tabPane));

        HBox toolbar = new HBox(openButton);
        toolbar.setSpacing(5);
        toolbar.setPadding(new Insets(5));
        root.setTop(toolbar);

        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.getIcons().add(new Image(iconSrc));
        primaryStage.show();
    }

    private void openImage(Stage primaryStage, TabPane tabPane) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle(TITLE);
        File file = fileChooser.showOpenDialog(primaryStage);
        if (file != null) {
            // Load the image and create an ImageView
            Image image = new Image(file.toURI().toString());
            imageView = new ImageView(image);
            imageView.setPreserveRatio(true);
            imageView.setFitWidth(primaryStage.getWidth() - 20);
            imageView.setFitHeight(primaryStage.getHeight() - 150);

            // Add the ImageView to the StackPane to center the display
            StackPane stackPane = new StackPane(imageView);

            // Update the bottom status bar
            Label statusLabel = new Label(SIZE_LABEL + "0" + UNIT + DIMENSIONS_LABEL + "0 x 0");

            DecimalFormat df = new DecimalFormat("#.00");
            double fileSize = (double) file.length() / 1024;
            String fileSizeStr = df.format(fileSize);
            int width = (int) image.getWidth();
            int height = (int) image.getHeight();
            String dimensionStr = width + " x " + height;
            statusLabel.setText(SIZE_LABEL + fileSizeStr + UNIT + DIMENSIONS_LABEL + dimensionStr);

            // Create a new Tab and add the ImageView and data display area to it
            BorderPane contentPane = new BorderPane(stackPane);
            contentPane.setBottom(statusLabel);

            Tab tab = new Tab(file.getName(), contentPane);
            tabPane.getTabs().add(tab);

            // Switch to a new Tab
            tabPane.getSelectionModel().select(tab);

            // Initializes the scale transform
            scaleTransform = new Scale(1, 1, 0, 0);

            // Add zoom
            imageView.setScaleX(1);
            imageView.setScaleY(1);
            imageView.setOnScroll(event -> {
                if (event.isControlDown()) {
                    double zoomFactor = 1.05;
                    if (event.getDeltaY() < 0) {
                        zoomFactor = 0.95;
                    }
                    Scale scale = new Scale(zoomFactor, zoomFactor, event.getX(), event.getY());
                    imageView.getTransforms().add(scale);
                    scaleTransform.setX(scaleTransform.getX() * zoomFactor);
                    scaleTransform.setY(scaleTransform.getY() * zoomFactor);
                }
            });

            // Add drag function
            Double[] lastPosition = new Double[2];
            imageView.setOnMousePressed(event -> {
                if (event.getButton() == MouseButton.PRIMARY) {
                    lastPosition[0] = event.getX();
                    lastPosition[1] = event.getY();
                }
            });
            imageView.setOnMouseDragged(event -> {
                if (event.getButton() == MouseButton.PRIMARY) {
                    double deltaX = event.getX() - lastPosition[0];
                    double deltaY = event.getY() - lastPosition[1];

                    // Convert the travel distance to the distance in the scaled coordinate system
                    double scaledDeltaX = deltaX * scaleTransform.getX();
                    double scaledDeltaY = deltaY * scaleTransform.getY();

                    imageView.setTranslateX(imageView.getTranslateX() + scaledDeltaX);
                    imageView.setTranslateY(imageView.getTranslateY() + scaledDeltaY);
                    lastPosition[0] = event.getX();
                    lastPosition[1] = event.getY();
                }
            });
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
